#include "IO/IFile.h"

namespace tyro
{
	namespace IO
	{
		//-----------------------------------------------------------------------------
		// Constructor
		//-----------------------------------------------------------------------------
		IFile::IFile()
		{

		}

		//-----------------------------------------------------------------------------
		// Open the file at specified file path
		//-----------------------------------------------------------------------------
		void IFile::Open(const char* filePath, bool read)
		{
			if( read )
			{
				fileStream.open (filePath, std::fstream::binary | std::fstream::in | std::fstream::out );
			}
			else 
			{
				fileStream.open (filePath, std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::trunc);
			}
		}

		//-----------------------------------------------------------------------------
		// Open with append 
		//-----------------------------------------------------------------------------
		void IFile::OpenAppend(const char *filePath)
		{
			fileStream.open( filePath, (std::fstream::binary | std::fstream::in | std::fstream::out | std::fstream::app) );
		}

		//-----------------------------------------------------------------------------
		// Read Bytes from file
		//-----------------------------------------------------------------------------
		unsigned int IFile::ReadBytes(char*& buffer, unsigned int numberOfBytes)
		{

			/* Read data size to buffer */
			fileStream.read(buffer, numberOfBytes);

			/* If read fails return 0 */
			if(fileStream.fail())
				return 0;

			/* Return the number of bytes read */
			return numberOfBytes;
		}

		//-----------------------------------------------------------------------------
		// Write Bytes to file
		//-----------------------------------------------------------------------------
		unsigned int IFile::WriteBytes(const char* const buffer, unsigned int numberOfBytes)
		{
			/* Check to see if the file is open */
			if( !IsOpen() )
				return 0;

			/* Write buffer to file */
			fileStream.write(buffer, numberOfBytes);

			/* If read fails return 0 */
			if(fileStream.fail())
				return 0;

			/* Return the number of bytes read */
			return numberOfBytes;
		}

		//-----------------------------------------------------------------------------
		// Close the current file stream
		//-----------------------------------------------------------------------------
		void IFile::Close()
		{
			if(IsOpen())
			{
				fileStream.close();
			}
		}

		//-----------------------------------------------------------------------------
		// Check if the file stream is open
		//-----------------------------------------------------------------------------
		bool IFile::IsOpen()
		{
			return fileStream.is_open();
		}

		//-----------------------------------------------------------------------------
		// Get the length of a file
		//-----------------------------------------------------------------------------
		UINT_32 IFile::Length()
		{
			unsigned int pos = fileStream.tellg();
				fileStream.seekg (0, std::ios::end);
				UINT_32 length = fileStream.tellg();
				fileStream.seekg (0, std::ios::beg);

				fileStream.seekg (pos, std::ios::beg);

				return length;
		}

	}
}